﻿/*
 * Buffer.h
 *
 *  Created on: 2011/05/29
 *      Author: naoki
 */

#ifndef INCLUDED_NTENGINE_BUFFER_H
#define INCLUDED_NTENGINE_BUFFER_H

#include "NTEngine/Base/Array.h"

namespace NTEngine {

/**
 * @brief 足し終わるまでアクセスせず、いくつ足すかがわからない、という用途のためのもの
 *  必要なデータを流し込んでからアクセスする場合などに用います。
 */
template<class T> class Buffer {
public:
	/**
	 * @brief コンストラクタ
	 */
	explicit Buffer( int blockSize = 16 );
	/**
	 * @brief デストラクタ
	 */
	~Buffer();

	/**
	 * brief 再確保
	 */
	void set( int blockSize );

	/**
	 * brief 現在の要素数取得
	 */
	int size() const;

	/**
	 * brief 全解放
	 */
	void clear();

	/**
	 * brief 末尾に空で追加。足したものへのポインタを返す
	 */
	T* add();

	/**
	 * brief 末尾に追加
	 */
	void add( const T& );

	/**
	 * brief 次へ
	 */
	void toNext();

	/**
	 * brief 終わり位置か問い合わせ
	 */
	bool isEnd() const;

	/**
	 * brief 現在の要素を取得(非const)
	 */
	T* get();

	/**
	 * brief 現在の要素を取得(const)
	 */
	const T* get() const;

	/**
	 * brief 最初の要素にポインタを戻す
	 */
	void rewind();

	/**
	 * brief 単なる配列に変換
	 */
	void copyTo( T* ) const;

	/**
	 * brief Arrayにコピー
	 */
	void copyTo( Array<T>* ) const;

private:
	struct Block {
		Block* m_Next;
		T* m_Elements;
	};
	Buffer& operator=( const Buffer& ); // 禁止
	Buffer( const Buffer& ); // 禁止

	int m_BlockSize; //
	int m_Size; //
	int m_LastPos; //
	int m_CurrentPos; //
	Block m_Head; //
	Block* m_LastBlock; //
	Block* m_CurrentBlock; //
};

} // namespace NTEngine

#include "NTEngine/Base/Impl/BufferImpl.h"

#endif //INCLUDED_NTENGINE_BUFFER_H
